package com.ruoyi.back.v2.service

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.date.DateUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.ruoyi.app.common.*
import com.ruoyi.back.domain.AppUser
import com.ruoyi.back.service.AppUserService
import com.ruoyi.back.v2.domain.*
import com.ruoyi.common.core.page.TableSupport
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
class SpreadManagerBackService {

    @Autowired
    private lateinit var appUserService: AppUserService

    @Autowired
    private lateinit var inviteDetailService: InviteDetailService

    @Autowired
    private lateinit var employeeDetailService: EmployeeDetailService

    @Autowired
    private lateinit var relationshipService: PromoteRelationshipService

    @Autowired
    private lateinit var withdrawalsDetailService: WithdrawalsDetailService


    fun appUsersQuery(spreadStatisticsSearchParam: SpreadStatisticsSearchParam): KtQueryWrapper<AppUser> =
        KtQueryWrapper(AppUser::class.java).let {
            it.eq(AppUser::promotionalRegistrationUser, true)

            if (StrUtil.isNotBlank(spreadStatisticsSearchParam.beginTime) && StrUtil.isNotBlank(
                    spreadStatisticsSearchParam.endTime
                )
            ) {
                it.gt(
                    StrUtil.isNotBlank(spreadStatisticsSearchParam.beginTime),
                    AppUser::registerDate,
                    spreadStatisticsSearchParam.beginTime.date()
                )
                it.lt(
                    StrUtil.isNotBlank(spreadStatisticsSearchParam.endTime),
                    AppUser::registerDate,
                    spreadStatisticsSearchParam.endTime.date()
                )
            } else {

                when (spreadStatisticsSearchParam.type) {
                    0 -> {
                        DateUtil.date().let { dateTime ->
                            it.eq(AppUser::year, DateUtil.year(dateTime))
                            it.eq(AppUser::month, DateUtil.month(dateTime))
                            it.eq(AppUser::day, DateUtil.dayOfMonth(dateTime))
                        }
                    }

                    1 -> {
                        DateUtil.yesterday().let { dateTime ->
                            it.eq(AppUser::year, DateUtil.year(dateTime))
                            it.eq(AppUser::month, DateUtil.month(dateTime))
                            it.eq(AppUser::day, DateUtil.dayOfMonth(dateTime))
                        }
                    }

                    2 -> {
                        DateUtil.date().let { dateTime ->
                            it.gt(AppUser::registerDate, DateUtil.offsetDay(dateTime, -7))
                            it.lt(AppUser::registerDate, dateTime)
                        }

                    }

                    else -> {
                        DateUtil.date().let { dateTime ->
                            it.gt(AppUser::registerDate, DateUtil.offsetDay(dateTime, -30))
                            it.lt(AppUser::registerDate, dateTime)
                        }
                    }
                }
            }
            it
        }


    fun Int.min(): Int = if (this - 3 < 0) 0 else this - 1


    /**
     * 获取推广注册用户新增趋势
     */
    fun spreadStatistics(spreadStatisticsSearchParam: SpreadStatisticsSearchParam): Data<SpreadStatistics> =
        Ok("获取数据成功", SpreadStatistics().apply {
            totalUserNum = appUserService.count(
                KtQueryWrapper(AppUser::class.java)
                    .eq(AppUser::promotionalRegistrationUser, true)
            )

            appUserService.list(appUsersQuery(spreadStatisticsSearchParam))
                .takeIf { it.isNotEmpty() }
                ?.let { appUsers ->
                    spreadAddUserData = initSpreadAddUserData().map {
                        it.apply {
                            userNum = appUsers.count { it.hour in time!!.toInt().min()..time!!.toInt() }
                            time = "$time:00"
                        }
                    }
                } ?: run { initSpreadAddUserData().map { it.apply { time = "$time:00" } } }

        })

    /**
     * 获取推广注册用户
     */
    fun spreadRegisterUser(spreadStatisticsSearchParam: SpreadStatisticsSearchParam): PageData<SpreadRegisterUser> =
        TableSupport.buildPageRequest().let { pageDomain ->
            appUserService.page(
                Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()),
                appUsersQuery(spreadStatisticsSearchParam)
            )
                .let { appUserPage ->

                    Page<SpreadRegisterUser>().apply {
                        BeanUtil.copyProperties(appUserPage, this)
                        appUserPage.records.takeIf { it.isNotEmpty() }
                            ?.run {
                                records = map {
                                    SpreadRegisterUser().apply {
                                        id = it.id
                                        userName = it.username
                                        userId = it.userId
                                        loginType = it.loginType
                                        consumerMoney = inviteDetailService.consumerMoney(it.id!!)
                                        totalEmployee = employeeDetailService.employeeMoney(it.id!!)

                                        relationshipService.userPromoteRelationShip(it.id!!)?.let {
                                            firstLevelUser = it.firstLevel
                                                ?.let { appUserService.getById(it)?.run { "$username($userId)" } }
                                                ?: "--"

                                            secondLevelUser = it.secondLevel
                                                ?.let { appUserService.getById(it)?.run { "$username($userId)" } }
                                                ?: "--"
                                        }
                                        registerTime = it.registerDate?.format()
                                    }
                                }
                            }

                    }.pageInfo()
                }

        }

    fun AppUser.spreadUserInfo() = SpreadUserInfo().apply {
        id = this@spreadUserInfo.id
        userId = this@spreadUserInfo.userId
        userName = this@spreadUserInfo.username
        inviteNum = inviteDetailService.userInviteUserNum(this@spreadUserInfo.id!!)
        consumerMoney = inviteDetailService.consumerMoney(this@spreadUserInfo.id!!)
        totalEmployee = employeeDetailService.employeeMoney(this@spreadUserInfo.id!!)
        haveWithdraw = withdrawalsDetailService.withdrawMoney(this@spreadUserInfo.id!!)
        relationshipService.userPromoteRelationShip(this@spreadUserInfo.id!!)?.let {
            employeeRetain = it.employeeMoney
            firstLevelEmployeeRetain = relationshipService.userPromoteRelationShip(it.firstLevel)?.employeeMoney ?: 0.0
            secondLevelEmployeeRetain =
                relationshipService.userPromoteRelationShip(it.secondLevel)?.employeeMoney ?: 0.0
        }
        withdrawalsDetailService.withdrawPreCheck(this@spreadUserInfo.id!!)?.let {
            withdrawApplication = it.money
            withdrawId = it.id
        }
    }

    /**
     * 获取推广信息
     */
    fun spreadUserInfo(spreadUserInfoSearchParam: SpreadUserInfoSearchParam): PageData<SpreadUserInfo> {
        return if (spreadUserInfoSearchParam.withdraw == null) {
            TableSupport.buildPageRequest().let { pageDomain ->
                appUserService.page(
                    Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()), KtQueryWrapper(AppUser::class.java)
                        .like(
                            StrUtil.isNotBlank(spreadUserInfoSearchParam.userInfo),
                            AppUser::username,
                            spreadUserInfoSearchParam.userInfo
                        )
                        .or()
                        .like(
                            StrUtil.isNotBlank(spreadUserInfoSearchParam.userInfo),
                            AppUser::userId,
                            spreadUserInfoSearchParam.userInfo
                        )
                        .orderByDesc(AppUser::registerDate)
                )
                    .let { appUserPage ->
                        Page<SpreadUserInfo>().apply {
                            BeanUtil.copyProperties(appUserPage, this)
                            appUserPage.records.takeIf { it.isNotEmpty() }
                                ?.run {
                                    records = map {
                                        it.spreadUserInfo()
                                    }
                                }
                        }.pageInfo()
                    }
            }
        } else {
            TableSupport.buildPageRequest().let { pageDomain ->
                withdrawalsDetailService.page(
                    Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()),
                    KtQueryWrapper(WithdrawalsDetail::class.java)
                        .eq(WithdrawalsDetail::checkStatus, 0)
                        .like(
                            StrUtil.isNotBlank(spreadUserInfoSearchParam.userInfo),
                            WithdrawalsDetail::username,
                            spreadUserInfoSearchParam.userInfo
                        )
                        .or()
                        .like(
                            StrUtil.isNotBlank(spreadUserInfoSearchParam.userInfo),
                            WithdrawalsDetail::userId,
                            spreadUserInfoSearchParam.userInfo
                        )
                        .orderByDesc(WithdrawalsDetail::createTime)
                )
                    .let { page ->
                        Page<SpreadUserInfo>().apply {
                            BeanUtil.copyProperties(page, this)
                            page.records.takeIf { it.isNotEmpty() }
                                ?.run {
                                    records = map {
                                        AppUser().apply {
                                            id = it.userId
                                            userId = it.userIdStr
                                            username = it.username
                                        }.spreadUserInfo()
                                    }
                                }
                        }.pageInfo()
                    }
            }
        }
    }

    /**
     * 推广信息查看
     */
    fun spreadUserLevelInfo(spreadUserInfoSearchParam: SpreadUserInfoSearchParam): PageData<SpreadUserLevelInfo> {

        return TableSupport.buildPageRequest().let { pageDomain ->
            inviteDetailService.page(
                Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()),
                KtQueryWrapper(InviteDetail::class.java)
                    .eq(
                        InviteDetail::userId, appUserService.getOne(
                            KtQueryWrapper(AppUser::class.java)
                                .eq(AppUser::userId, spreadUserInfoSearchParam.userId)
                        )?.id
                    )
                    .eq(
                        spreadUserInfoSearchParam.levelType != null,
                        InviteDetail::inviteLevel,
                        spreadUserInfoSearchParam.levelType
                    )
                    .like(
                        StrUtil.isNotBlank(spreadUserInfoSearchParam.userInfo),
                        InviteDetail::inviteUserName,
                        spreadUserInfoSearchParam.userInfo
                    )
                    .or()
                    .like(
                        StrUtil.isNotBlank(spreadUserInfoSearchParam.userInfo),
                        InviteDetail::inviteUserId,
                        spreadUserInfoSearchParam.userInfo
                    )
            )
        }.let { inviteDetailPage ->
            Page<SpreadUserLevelInfo>().apply {
                BeanUtil.copyProperties(inviteDetailPage, this)
                inviteDetailPage.records.takeIf { it.isNotEmpty() }
                    ?.run {
                        records = map {
                            val appUser = appUserService.getById(it.inviteUserId)
                            val spreadUserInfo1 = appUser.spreadUserInfo()
                            SpreadUserLevelInfo().apply {
                                BeanUtil.copyProperties(spreadUserInfo1, this)
                                levelType = it.inviteLevel
                            }
                        }
                    }
            }.pageInfo()
        }
    }

    /**
     * 提现记录
     */
    fun withdrawRecord(userId: Long): PageData<WithdrawRecord> =
        TableSupport.buildPageRequest().let { pageDomain ->
            withdrawalsDetailService.withdrawPage(pageDomain.pageNum.toInt(), pageDomain.pageSize.toInt(), userId)
                .let { withdrawalsDetailPage ->
                    Page<WithdrawRecord>().apply {
                        BeanUtil.copyProperties(withdrawalsDetailPage, this)
                        withdrawalsDetailPage.records.takeIf { it.isNotEmpty() }
                            ?.run {
                                records = map {
                                    WithdrawRecord().apply {
                                        BeanUtil.copyProperties(it, this)
                                    }
                                }
                            }
                    }.pageInfo()
                }
        }


    /**
     * 提现审核
     */
    fun withdrawCheck(withDrawCheck: WithDrawCheck): Data<Boolean> {

       return withdrawalsDetailService.getById(withDrawCheck.withdrawId)?.let {

            when (withDrawCheck.checkStatus) {

                1 -> {

                    //提现操作

                    //减少当前用户收益余额
                    relationshipService.userPromoteRelationShip(it.userId)?.run {
                        relationshipService.updateById(this.apply {
                            employeeMoney = (employeeMoney ?: 0.0).minus(it.money ?: 0.0)
                        })
                    }

                    //更新为审核成功
                    withdrawalsDetailService.updateById(it.apply {
                        checkStatus = 1
                    })
                }
                else -> {
                    //更新为审核失败
                    withdrawalsDetailService.updateById(it.apply {
                        checkStatus = 2
                        errorMsg = withDrawCheck.errorMsg
                    })

                }
            }

            Ok("操作成功", true)
        } ?: Fail("当前审核id不存在")
    }

    /**
     * 修改用户收益余额
     */
    fun updateUserEmployeeMoney(updateEmployeeMoney: UpdateEmployeeMoney): Data<Boolean> =
        relationshipService.userPromoteRelationShip(updateEmployeeMoney.userId)?.let {
            Ok("修改成功", relationshipService.updateById(it.apply {
                employeeMoney = updateEmployeeMoney.money
            }))
        } ?: Fail("不存在该用户!")

}